#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ADMIN_PASSWORD "qwert"

typedef struct record {
  char content[12];
  char way[12];
  char flag1; /*a,b,c 分别为按月，按年，按金额交费。*/
  char flag2; /*e,f,g,h 分别为电，水，气，暖气费 */
} RECORD;

typedef struct users {
  char name[16];
  char password[16];
} USERS;

void coverUser();      /*用户界面*/
void signIn();         /*用户登录*/
void signUp();         /*用户注册*/
void coverAdmin();     /*管理员界面*/
void selectPower();    /*选择权限*/
void selectPay();      /*选择交费内容*/
void selectWay();      /*选择交费方式*/
void queryFeeRecord(); /*查询交费记录*/
int selectSee();       /*选择查询方式*/
void modifyRecode();   /*修改记录*/
void deleteRecode();   /*删除记录*/
void deleteUser();     /*删除用户*/

int choose;
RECORD record;
USERS active_user;

int main(void) {
  while (1) {
    printf(" -------------------------------\n");
    printf("| 欢迎使用<用户生活交费管理系统> |\n");
    printf(" -------------------------------\n");
    selectPower();
  }

  return 0;
}

void coverUser() {
  while (1) {
    printf("\n\n已进入用户界面.\n");
    printf("1. 选择交费内容\n");
    printf("2. 查询交费记录\n");
    printf("0. 退出系统\n");
    scanf("%d", &choose);
    switch (choose) {
    case 1:
      selectPay();
      break;
    case 2:
      queryFeeRecord();
      break;
    case 0:
      exit(0);
    default:
      printf("无效输入,请重新选择。\n");
    }
  }

  return;
}

void coverAdmin() {
  while(1){
    printf("\n已进入管理员界面.\n");
    printf("1. 修改交费记录\n");
    printf("2. 删除交费记录\n");
    printf("3. 删除用户\n");
    printf("0. 退出系统\n");
    scanf("%d", &choose);
    switch (choose) {
    case 0: /*退出系统*/
      exit(0);
      break;
    case 1:
      modifyRecode(); /*修改记录*/
      break;
    case 2:
      deleteRecode(); /*删除记录*/
      break;
    case 3:
      deleteUser(); /*删除用户*/
      break;
    default:
      printf("无效的选项，请重新选择。\n");
    }
  }
  return;
}

void selectPower() {
  int i;
  char password[20];

  printf("请选择登录方式:\n");
  printf("1.用户登录\n2.管理员登录\n3.注册\n0.退出系统\n");

  scanf("%d", &choose);
  if (choose == 1) {
    signIn();               /*进入用户登录界面*/
  } else if (choose == 2) { /*管理员登录*/
    printf("\n请输入管理员密码：");
    for (i = 0; i < 3; i++) {
      scanf("%s", password);
      if (strcmp(password, ADMIN_PASSWORD) == 0) {
        coverAdmin(); /*进入管理员界面*/
      } else {
        printf("密码输入错误，请重新输入\n");
        printf("请输入密码:");
      }
    }
    if(i == 3) {
      printf("密码输入错误次数太多，将退出系统");
    }
    exit(0);
  } else if (choose == 3) {
    signUp(); /*进入注册界面*/
  } else if (choose == 0) {
    exit(0); /*退出系统*/
  }

  return;
}

void selectPay() { /*选择交费内容*/
  FILE *fp;
  printf("请选择交费内容:\n");
  printf("1. 电费\n");
  printf("2. 水费\n");
  printf("3. 气费\n");
  printf("4. 暖气费\n");
  scanf("%d", &choose);
  switch (choose) {
  case 1:
    strcpy(record.content, "电费");
    record.flag2 = 'e';
    break;
  case 2:
    strcpy(record.content, "水费");
    record.flag2 = 'f';
    break;
  case 3:
    strcpy(record.content, "气费");
    record.flag2 = 'g';
    break;
  case 4:
    strcpy(record.content, "暖气费");
    record.flag2 = 'h';
    break;
  default:
    printf("无效输入,请重新选择。\n");
  }
  selectWay(); /*选择交费方案*/
}

void signUp() { /*注册*/
  USERS read;
  FILE *fp;
  char *p;
  printf(" ------------------------------\n");
  printf("|        欢迎进入注册界面       |\n");
  printf(" ------------------------------\n");
  printf("帐号：");
  scanf("%s", active_user.name); /*输入帐号*/
  fp = fopen("users.txt", "r");  /*打开保存用户帐号密码的文件*/
  while (1) {                    /*死循环*/
    fread(&read, sizeof(struct users), 1, fp); /*从头开始读取每一个用户的信息*/
    if (strcmp(active_user.name, read.name) == 0) {
      printf("用户已存在,请重新输入帐号：");
      scanf("%s", active_user.name); /*重新输入帐号*/
      rewind(fp);                    /*指向文件开头*/
      continue;                      /*跳过本次循环*/
    }
    if (feof(fp)) {
      break;
    }
  }
  fclose(fp);
  printf("密码：");
  scanf("%s", active_user.password); /*输入密码*/
  fp = fopen("users.txt", "a");
  fwrite(&active_user, sizeof(struct users), 1, fp);
  fclose(fp);
  printf("注册成功，将自动登录...");
  coverUser(); /*进入用户界面*/
}

void signIn() { /*登录*/
  int i;
  USERS read;
  FILE *fp;
  printf(" ------------------------------\n");
  printf("|        欢迎进入登录界面       |\n");
  printf(" ------------------------------\n");
  printf("帐号：");
  scanf("%s", active_user.name); /*输入帐号*/
  fp = fopen("users.txt", "r");  /*打开保存用户帐号密码的文件*/
  while (1) {                    /*死循环*/
    fread(&read, sizeof(struct users), 1, fp); /*从头开始读取每个用户的信息*/
    if (strcmp(active_user.name, read.name) == 0) {
      break;
    }
    if (feof(fp)) {
      printf("用户不存在,请重新输入帐号：");
      scanf("%s", active_user.name); /*重新输入帐号*/
      rewind(fp);                    /*指向文件开头*/
      continue;                      /*跳过本次循环*/
    }
  }
  fclose(fp);
  printf("密码：");
  scanf("%s", active_user.password);
  for (i = 0; i < 3; i++) { /*只允许输入三次密码，错误次数过多将退出系统*/
    if (strcmp(active_user.password, read.password) == 0) {
      break;
    } else {
      printf("密码输入错误，请重新输入：");
      scanf("%s", active_user.password);
    }
  }
  if (i == 3) {
    printf("密码输入次数过多，系统将退出!");
    exit(0); /*退出系统*/
  } else {
    coverUser(); /*密码输入成功，进入用户界面*/
  }
}

void selectWay() {
  char money[15]; /*和record.way对应*/
  FILE *fp;
  printf("请选择缴纳费用的方案：\n");
  printf("1. 按月\n");
  printf("2. 按年\n");
  printf("3. 按金额\n");
  scanf("%d", &choose);
  switch (choose) {
  case 1:
    strcpy(record.way, "按月");
    record.flag1 = 'a';
    break;
  case 2:
    strcpy(record.way, "按年");
    record.flag1 = 'b';
    break;
  case 3:
    printf("请输入要缴纳的金额：");
    scanf("%s", money);
    strcpy(record.way, money);
    record.flag1 = 'c';
    break;
  }
  fp = fopen(active_user.name, "a");
  fwrite(&record, sizeof(struct record), 1, fp);
  fclose(fp);

  return;
}

void queryFeeRecord() {
  FILE *fp;
  int i = 1;
  int choose;
  if ((fp = fopen(active_user.name, "r")) == NULL) {
    printf("没有交费记录。\n");
    return;
  }
  choose = selectSee();
  fread(&record, sizeof(struct record), 1, fp);
  if (feof(fp)) { /*若文件没有内容*/
    printf("交费记录为空\n\n");
    return;
  }
  printf("  %8s  %s\n", "缴费内容", "交费方式");
  while (1) {
    switch (choose) { /*读取struct record中的flag1,flag2*/
    case 1:
      if (record.flag1 == 'a') {
        printf("%2d.%8s %s\n", i, record.content, record.way);
        i++;
      }
      break;
    case 2:
      if (record.flag1 == 'b') {
        printf("%2d.%8s | %s\n", i, record.content, record.way);
        i++;
      }
      break;
    case 3:
      if (record.flag1 == 'c') {
        printf("%2d.%8s | %s\n", i, record.content, record.way);
        i++;
      }
      break;
    case 4:
      if (record.flag2 == 'e') {
        printf("%2d.%8s | %s\n", i, record.content, record.way);
        i++;
      }
      break;
    case 5:
      if (record.flag2 == 'f') {
        printf("%2d.%8s | %s\n", i, record.content, record.way);
        i++;
      }
      break;
    case 6:
      if (record.flag2 == 'g') {
        printf("%2d.%8s | %s\n", i, record.content, record.way);
        i++;
      }
      break;
    case 7:
      if (record.flag2 == 'h') {
        printf("%2d.%8s | %s\n", i, record.content, record.way);
        i++;
      }
      break;
    case 8:
      printf("%2d.%8s | %s\n", i, record.content, record.way);
      i++;
      break;
    default:
      printf("无效选项，请重新选择\n");
      choose = selectSee();
    }
    fread(&record, sizeof(struct record), 1, fp); /*读取下一个记录*/
    if (feof(fp)) { /*到文件结尾时退出函数*/
      fclose(fp);
      return;
    }
  }
  return;
}

int selectSee() { /*选择查询方式*/
  int choose;
  printf("请选择你要查看的内容:\n");
  printf("1. 按月交费\n");
  printf("2. 按年交费\n");
  printf("3. 按金额交费\n");
  printf("4. 电费\n");
  printf("5. 水费\n");
  printf("6. 气费\n");
  printf("7. 暖气费\n");
  printf("8. 全部\n");
  scanf("%d", &choose);
  return choose;
}

void deleteUser() {
  USERS tmp; /*用来临时保存文件中读取的用户姓名*/
  FILE *fp1, *fp2;
  printf("\n请输入你想要删除的用户名:");
  scanf("%s", active_user.name);
  fp1 = fopen("users.txt", "r");
  fp2 = fopen("temp.txt", "w");
  while(fread(&tmp, sizeof(struct users), 1, fp1)) { /*除了要删除的用户名，其他都保存到另一个文件*/
    if(strcmp(active_user.name, tmp.name) != 0) {
      fwrite(&tmp, sizeof(struct users), 1, fp2);
    }
  }
  fclose(fp1);
  fclose(fp2);
  remove(active_user.name); /*删除用户储存交费记录的文件*/
  remove("users.txt"); /*删除原本的用户记录*/
  rename("temp.txt", "users.txt"); /*将修改的临时文件改成用户记录*/
  printf("\n删除用户成功");

  return;
}

void modifyRecode() {
  char money[15];
  RECORD tmp;
  FILE *fp1, *fp2;
  int n = 1, i = 1;
  printf("\n请输入要修改的记录对应的用户名：");
  scanf("%s", active_user.name);
  fp1 = fopen(active_user.name, "r+");
  printf("\n");
  while(fread(&record, sizeof(struct record), 1, fp1)) { /*将该用户所有记录输出*/
    printf("%2d.%8s | %s\n", n, record.content, record.way);
    n++;
  }
  rewind(fp1); /*重新指向文件开头*/
  printf("\n请输入上方左侧编号，选择要修改的记录：");
  scanf("%d", &n);
  while(fread(&tmp, sizeof(struct record), 1, fp1)) {/*从头开始读取每一个记录*/
    if(i == n) {
      break; /*读取到选取的记录为止*/
    }
    i++;
  }
  printf("\n以下为选取的记录\n");
  printf("%8s | %s\n", tmp.content, tmp.way); /*将选择的记录再打印出来*/
  printf("----------------------------------------\n");

  printf("\n请选择你要修改的内容:\n");
  printf("1. 交费内容\n");
  printf("2. 交费方案\n");
  scanf("%d", &i);
  printf("\n请选择要修改为:\n");
  switch(i) {
    case 1:
      printf("1. 电费\n");
      printf("2. 水费\n");
      printf("3. 气费\n");
      printf("4. 暖气费\n");
      scanf("%d", &choose);
      switch (choose) {
      case 1:
        strcpy(tmp.content, "电费");
        tmp.flag2 = 'e';
        break;
      case 2:
        strcpy(tmp.content, "水费");
        tmp.flag2 = 'f';
        break;
      case 3:
        strcpy(tmp.content, "气费");
        tmp.flag2 = 'g';
        break;
      case 4:
        strcpy(tmp.content, "暖气费");
        tmp.flag2 = 'h';
        break;
      default:
        printf("无效输入,请重新选择。\n");
      }
      break;
    case 2:
      printf("1. 按月交费\n");
      printf("2. 按年交费\n");
      printf("3. 按金额交费\n");
      scanf("%d", &choose);
      switch (choose) {
      case 1:
        strcpy(tmp.way, "按月");
        tmp.flag1 = 'a';
        break;
      case 2:
        strcpy(tmp.way, "按年");
        tmp.flag1 = 'b';
        break;
      case 3:
        printf("请输入要缴纳的金额：");
        scanf("%s", money);
        strcpy(tmp.way, money);
        tmp.flag1 = 'c';
        break;
      }
      break;
    }
  fclose(fp1);
  fp1 = fopen(active_user.name, "r+");
  fp2 = fopen("temp.txt", "w");
  i = 1;
  while(fread(&record, sizeof(struct record), 1,fp1)) {/*从头开始读取每一个记录*/
    if(i != n) {
      fwrite(&record, sizeof(struct record), 1, fp2);
    } else if (i == n) {
      fwrite(&tmp, sizeof(struct record), 1, fp2);
    }
    i++;
  }
  fclose(fp1);
  fclose(fp2);
  remove(active_user.name);
  rename("temp.txt", active_user.name);
  printf("\n修改完成\n");

    return;
}

void deleteRecode() { /*删除记录*/
  RECORD tmp;
  int i = 1, n = 1;
  FILE *fp1, *fp2;
  printf("\n请输入要删除的记录对应的用户名：");
  scanf("%s", active_user.name);
  fp1 = fopen(active_user.name, "r+");
  printf("\n");
  while(fread(&record, sizeof(struct record), 1, fp1)){ /*将该用户所有记录输出*/
    printf("%2d.%8s | %s\n", n, record.content, record.way);
    n++;
  }
  rewind(fp1);
  printf("\n请输入上方左侧编号，选择要删除的记录：");
  scanf("%d", &choose);
  fp2 = fopen("temp.txt", "w"); /*将需要的记录写入临时文件*/
  while(fread(&tmp, sizeof(struct record), 1,fp1)) {/*从头开始读取每一个记录*/
    if(i != choose) { /*将需要的数据写入临时文件*/
      fwrite(&tmp, sizeof(struct record), 1, fp2);
    }
    i++;
  }
  fclose(fp1);
  fclose(fp2);
  remove(active_user.name);
  rename("temp.txt", active_user.name);
  printf("\n删除记录成功\n");

  return;
}
